import {
  FC,
  FormEvent,
  FormEventHandler,
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
} from "react";
import { isSameElement } from "../../../../utils";
import EmojiWrapper from "../emoji-wrapper";
import AtWrapper from "../at-wrapper";
import FileWrapper from "../file-wrapper";
import { Button } from "antd";
// interface IndexProp {
//   setAtRootStyle: React.Dispatch<
//     React.SetStateAction<{
//       left: number;
//       top: number;
//       open: boolean;
//     }>
//   >;
// }
// 可编辑库可以参考 https://github.com/zurb/tribute
const Index = (props: any, ref: any) => {
  // 最后@符号的位置信息
  const selectionRef = useRef<any>(null);
  // 缓存range (用户点击input输入框后，然后点击emoji图标，点击后range就会变为点击的元素，所以要把input的焦点位置缓存起来)
  const rangeRef = useRef<any>(null);
  const atWrapperRef = useRef<any>(null);
  const inputRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const handler = (v: any) => {
      console.log("selectionchange", v);
      const selection = window.getSelection();
      if (!selection || selection.rangeCount <= 0) return false;
      const range = selection.getRangeAt(0);
      console.log("selectionchange-range", range);
      if (isSameElement(inputRef.current, range.endContainer)) {
        console.log("相同");
        rangeRef.current = range;
      }
    };
    document.addEventListener("selectionchange", handler);
    return () => {
      document.removeEventListener("selectionchange", handler);
    };
  });

  // 监听页面的改变
  const handleChatInput: FormEventHandler<HTMLDivElement> = (
    v: FormEvent<HTMLDivElement>
  ) => {
    // 获取光标位置
    const selection = window.getSelection();
    selectionRef.current = selection;
    if (!selection?.focusNode) return false;
    // 解决换行生成的的br标签产生的问题
    if (
      !selection.focusNode ||
      !selection.focusNode.nodeValue ||
      selection.focusOffset === 0
    )
      return false;
    const range = selection.getRangeAt(0);
    rangeRef.current = range;

    const lastWord = selection.focusNode.nodeValue[selection.focusOffset - 1];
    if (lastWord !== "@") return false;
    // selectionRef.current = selection
    // 获取选中区域的范围 获取光标的范围
    // 返回一个包含当前选区内容的区域对象。 该参数指定需要被处理的子集编号（从零开始计数）。如果该数值被错误的赋予了大于或等于 rangeCount 结果的数字，将会产生错误。

    // 获取选中区域的边界 获取当前光标的坐标点 这个方法里面都有getBoundingClientRect()
    const rect = range.getBoundingClientRect();
    // console.log(rect)

    atWrapperRef.current?.setAtRootStyle({
      left: rect.left,
      top: rect.top,
      open: true,
    });
   
  };

  // 选择@的用户
  const handleSelectAt = (userInfo: any) => {
    console.log('handleSelectAt')
    // if (!selectionRef.current) return false;
    if (!rangeRef.current) return false
    const range = rangeRef.current
    console.log('range', range)
    // 将@符号替换为<span>@XXX</span>

    
    // 创建元素
    const atEle = document.createElement("span");
    // 为了删除的时候能将span整体给删除
    atEle.setAttribute("contenteditable", "false");
    atEle.setAttribute("data-uid", userInfo.id);
    atEle.innerHTML = `@${userInfo.name}`;
    atEle.classList.add("at-content");
    // 前后不能由contenteditable=false元素，在内容变化时，可以判断前后是否还有空格，没有就手动追加，目前只能想到这种解决办法（删除不掉的bug）
    // https://segmentfault.com/q/1010000039016347


    // 获取光标在那个节点位置上
    const fragment = document.createDocumentFragment()
    const spaceText = document.createTextNode('\u00A0')
    fragment.appendChild(spaceText)
    fragment.appendChild(atEle)
    range.insertNode(fragment);

    if (range.startContainer) {
      // 判断当前节点是否是文本节点text
      if (range.startContainer.nodeType === 3) {
        if (range.startContainer.nodeValue === "@") {
          // 一个text节点只有一个@元素时，直接将其删除(如果不删除会出现许多空的text节点)
          range.startContainer.parentElement.removeChild(range.startContainer);
        } else {
          // 将最后@符号删除
          range.startContainer.nodeValue =
            range.startContainer.nodeValue.replace(/@[^@]{0,}$/, "");
        }
        // if (/^@[^@]{0,}$/.test(range.startContainer.nodeValue)) {
        //   // 一个text节点只有一个@元素时，直接将其删除(如果不删除会出现许多空的text节点)
        //   range.startContainer.parentElement.removeChild(range.startContainer);
        // } else {
        //   // 将最后@符号删除 
        //   range.startContainer.nodeValue =  range.startContainer.nodeValue.replace(/@[^@]{0,}$/, "");
        //     // range.startContainer.nodeValue.replace(/@$/, "");
        // }
      } else {
        console.log("不是文本节点，暂不处理");
      }
    }

    // 将光标设置到新增加的@xx之后
    range.setStartAfter(atEle);
    // const spaceText = document.createElement('span')
    // spaceText.setAttribute('contenteditable', 'false')
    // range.insertNode(spaceText);
    // range.setStartAfter(spaceText);
    
    // range.setEnd(atEle, 1);
    // range.collapse(true);
    // 获取焦点
    inputRef.current?.focus();
    

  };

  // 选择emoji
  const handleSelectEmoji = (emojiValue: string) => {
    if (!inputRef.current) return false;
    if (!selectionRef.current) {
      // input输入框为空
      inputRef.current.innerHTML = inputRef.current.innerHTML + emojiValue;
    } else {
      console.log(rangeRef.current);

      if (rangeRef.current && rangeRef.current.endContainer) {
        // rangeRef.current.endContainer.nodeValue += emojiValue
        // 当在输入框中选中内容，选中的内容是同一个节点
        if (rangeRef.current.startContainer === rangeRef.current.endContainer) {
          
          if (rangeRef.current.startContainer.nodeType === 3) {
            const strList = rangeRef.current.startContainer.nodeValue.split("");
            const { startOffset, endOffset, startContainer, endContainer } =
              rangeRef.current;
            //      1 -                 5
            // ['1', '2', '3', '4', '5', '6']
            strList.splice(startOffset, endOffset - startOffset, emojiValue);
            startContainer.nodeValue = strList.join("");
            // 设置光标位置
            const range = selectionRef.current.getRangeAt(0);
            // range.setStartAfter(startContainer);

            range.setStart(startContainer, startOffset + emojiValue.length);
            range.setEnd(startContainer, startOffset + emojiValue.length);
            // range.setEnd(endContainer, endOffset + emojiValue.length)
            inputRef.current?.focus();
          } else {
            // 元素节点
            const { startOffset, endOffset, startContainer, endContainer } =
            rangeRef.current;
            // rangeRef.current.commonAncestorContainer
            const textNode = document.createTextNode(emojiValue);
            if (
              rangeRef.current.endOffset ===
              rangeRef.current.commonAncestorContainer.childNodes.length
            ) {
              rangeRef.current.commonAncestorContainer.appendChild(textNode);
             
            } else {
              rangeRef.current.commonAncestorContainer.insertBefore(
                textNode,
                rangeRef.current.commonAncestorContainer.childNodes[
                  rangeRef.current.endOffset
                ]
              );
            }
            
            // 设置光标
            const range = selectionRef.current.getRangeAt(0);
            range.setStartAfter(textNode)
            inputRef.current?.focus();
          }
        } else {
          // 选中的元素是多个元素，那么就需要将选中的元素给删除掉
          if (!rangeRef.current.commonAncestorContainer) return false;
          let isCanDelete = false; // 是否可以删除
          const range = selectionRef.current.getRangeAt(0);
          const { startOffset, endOffset, startContainer, endContainer } =
            rangeRef.current;
          Array.from(
            rangeRef.current.commonAncestorContainer.childNodes
          ).forEach((one) => {
            if (one === rangeRef.current.endContainer) {
              isCanDelete = false;
            }
            if (isCanDelete) {
              rangeRef.current.commonAncestorContainer.removeChild(one);
            } else if (one === rangeRef.current.startContainer) {
              isCanDelete = true;
            }
          });
          if (rangeRef.current.startContainer.nodeType === 3) {
            // 删除start节点
            const strStartList =
              rangeRef.current.startContainer.nodeValue.split("");
            strStartList.splice(rangeRef.current.startOffset);
            strStartList.push(emojiValue);
            rangeRef.current.startContainer.nodeValue = strStartList.join("");

            if (rangeRef.current.endContainer.nodeType === 3) {
              // 删除end节点
              const strEndList =
                rangeRef.current.endContainer.nodeValue.split("");
              strEndList.splice(0, rangeRef.current.endOffset);
              rangeRef.current.endContainer.nodeValue = strEndList.join("");
            }

            range.setStart(startContainer, startOffset + emojiValue.length);
            range.setEnd(startContainer, startOffset + emojiValue.length);
            // range.setEnd(endContainer, endOffset + emojiValue.length)
            inputRef.current?.focus();
            // 删除
          } else if (rangeRef.current.endContainer.nodeType === 3) {
            if (rangeRef.current.startContainer.nodeType === 3) {
              const strStartList =
                rangeRef.current.startContainer.nodeValue.split("");
              strStartList.splice(rangeRef.current.startOffset);
              rangeRef.current.startContainer.nodeValue = strStartList.join("");
            }

            const strEndList =
              rangeRef.current.endContainer.nodeValue.split("");
            strEndList.splice(0, rangeRef.current.endOffset);
            strEndList.unshift(emojiValue);
            rangeRef.current.endContainer.nodeValue = strEndList.join("");

            range.setStart(endContainer, emojiValue.length);
            range.setEnd(endContainer, emojiValue.length);
            // range.setEnd(endContainer, endOffset + emojiValue.length)
            inputRef.current?.focus();
          } else {
          }
        }
      }
    }
  };

  // 选中文件
  const handleSelectFiles = (list: any) => {

  }

  const onShowAtWrapper = (event: any) => {
    const rect = event.target.getBoundingClientRect()
    console.log('rangeRef.current', rangeRef.current)
    atWrapperRef.current?.setAtRootStyle({
      left: rect.left,
      top: rect.top,
      open: true,
    });
  }

  const handleKeyDown= (event: any) => {
    console.log('event', event)
    event.stopPropagation()
  }

  const handlePaste = (e: any) => {
    // 监听粘贴内容到输入框事件，对内容进行处理 处理掉复制的样式标签，只拿取文本部分
    e.stopPropagation()
    e.preventDefault()
    let text = '', event = (e.originalEvent || e)
    if (event.clipboardData && event.clipboardData.getData) {
      text = event.clipboardData.getData('text/plain')
      // @ts-ignore
    } else if (window.clipboardData && window.clipboardData.getData) {
       // @ts-ignore
      text = window.clipboardData.getData('text')
    }
    if (document.queryCommandSupported('insertText')) {
      document.execCommand('insertText', false, text)
    } else {
      document.execCommand('paste', false, text)
    }
  }

  // 子组件向外界暴漏
  // useImperativeHandle(ref, () => {
  //   return {
  //       handleSelectAt
  //   }
  // })
  return (
    <div className="bg-[#424656]  flex items-center px-5 py-1">
      <div className="tools-menu flex items-center mr-3">
        <div className="tools-item w-[26px] aspect-square rounded-md hover:bg-gray-800 flex flex-col cursor-pointer duration-300">
          <i className="voice-ani michat icon-voice block m-auto !text-lg text-white"></i>
        </div>
      </div>
    {/* 找到原因：由于默认的最小尺寸是内容尺寸，所以当设置 white-space: nowrap 时，文本不能自动换行，内容宽度就开始撑出。所以我们主动告诉渲染引擎最小宽度是0，你放心缩好了，溢出问题就解决了。 */}
     <div className="flex-1 relative min-w-0">
      <div
          ref={inputRef}
          onInput={handleChatInput}
          spellCheck="false"
          data-placeholder="你的骚话吧~"
          className="input-chat w-full text-white rounded-md px-3 py-1 duration-300 outline-none border border-opacity-0 focus:border-opacity-100 border-blue-500 max-h-[150px] overflow-y-auto"
          suppressContentEditableWarning 
          contentEditable="true"
          onPaste={handlePaste}
        ></div>
        <div className="absolute right-[5px] bottom-[3px]">
          <Button type="primary" size="small">发送</Button>
        </div>
     </div>
      <div className="tools-menu flex items-center ml-3">
        <EmojiWrapper handleSelectEmoji={handleSelectEmoji}>
          <div className="tools-item select-none w-[26px] aspect-square rounded-md hover:bg-gray-800 flex flex-col cursor-pointer duration-300">
            <i className="michatcolor icon-happy1 block m-auto !text-lg"></i>
          </div>
        </EmojiWrapper>

        <div className="show-at-wrapper select-none tools-item w-[26px] aspect-square rounded-md hover:bg-gray-800 flex flex-col cursor-pointer duration-300"
          onClick={onShowAtWrapper}
        >
          <i className="michatcolor icon-at block m-auto !text-lg"></i>
        </div>

        <div className="tools-item select-none w-[26px] aspect-square rounded-md hover:bg-gray-800 flex flex-col cursor-pointer duration-300">
          <i className="michatcolor icon-tupian block m-auto !text-lg"></i>
        </div>

        <FileWrapper>
          <div className="tools-item select-none w-[26px] aspect-square rounded-md hover:bg-gray-800 flex flex-col cursor-pointer duration-300">
            <i className="michatcolor icon-wenjianjia2 block m-auto !text-lg"></i>
           </div>
        </FileWrapper>
        
      </div>
      {/* AT */}
      <AtWrapper ref={atWrapperRef} handleSelectAt={handleSelectAt}></AtWrapper>
    </div>
  );
};

export default forwardRef(Index);
